//
//  HMRefreshControl.swift
//  01-自定义下拉刷新控件
//
//  Created by itcast on 17/3/27.
//  Copyright © 2017年 itcast. All rights reserved.
//

import UIKit
/*
    - 分析控件状态
        - 正常中
        - 下拉中
        - 刷新中
    - 分析控件状态切换的临界点 -114(64 + 控件的高度)
        - 如果拖动中没有松手 (一共有两种状态 正常中 下拉中)
            - contentOffset.y >= -114 (正常中)
            - contentOffset.y < -114 (下拉中)
        - 如果拖动后松手 
            - 如果当前的状态为下拉中 那么就要进入刷新中
 
 */
// 自定义下拉刷新控件高度
private let refreshControlH: CGFloat = 50
// 自定义下拉刷新状态枚举
enum HMRefreshControlType: String{
    case normal = "正常中"
    case pulling = "下拉中"
    case refreshing = "刷新中"
}
class HMRefreshControl: UIControl {
    
    // 记录父控件
    var scrollView: UIScrollView?
    // 记录当前的状态
    var refreshControlType: HMRefreshControlType = .normal{
        didSet{
            // 设置指示文字内容
            // refreshControlType.rawValue 通过枚举的名 得到对应的值
            messageLabel.text = refreshControlType.rawValue
            switch refreshControlType {
            case .normal:
//                messageLabel.text = "正常中"
                // 如果上一个状态为刷新中再执行动画
                if oldValue == .refreshing {
                    // 设置动画
                    UIView.animate(withDuration: 0.25, animations: {
                        self.scrollView?.contentInset.top -= refreshControlH
                        // 停止风火轮动画
                        self.indicatorView.stopAnimating()
                    }, completion: { (_) in
                        // 显示指示箭头
                        self.refreshImageView.isHidden = false
                    })
                }
                
                // 设置动画
                UIView.animate(withDuration: 0.25, animations: {
                    self.refreshImageView.transform = CGAffineTransform.identity
                })
                
            case .pulling:
//                messageLabel.text = "下拉中"
                // 设置动画
                UIView.animate(withDuration: 0.25, animations: { 
                    self.refreshImageView.transform = CGAffineTransform(rotationAngle: CGFloat(-3*M_PI))
                })
            case .refreshing:
//                messageLabel.text = "刷新中"
                UIView.animate(withDuration: 0.25, animations: {
                    self.scrollView?.contentInset.top += refreshControlH
                    // 隐藏指示箭头
                    self.refreshImageView.isHidden = true
                    // 开启风火轮动画
                    self.indicatorView.startAnimating()
                }, completion: { (_) in
                    // 发送事件 告知外界监听控件触发
                    self.sendActions(for: UIControlEvents.valueChanged)
                })
            }
        }
    }

    override init(frame: CGRect) {
        super.init(frame: CGRect(x: 0, y: -refreshControlH, width: UIScreen.main.bounds.size.width, height: refreshControlH))
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //MARK: 供外界调用的方法 结束刷新
    func endRefreshing(){
        // 吧控件的状态改为正常
        refreshControlType = .normal
    }
    
    //MARK: 设置视图
    private func setupUI(){
        backgroundColor = UIColor.orange
        // 添加控件
        addSubview(messageLabel)
        addSubview(refreshImageView)
        addSubview(indicatorView)
        // 系统约束
        // 取消自动布局
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        // 设置约束
        /*
            - 01 约束的对象
            - 02 约束对象的部位
            - 03 约束条件
            - 04 相对于约束的对象
            - 05 相对于约束的对象部位
            - 06 倍数
            - 07 浮点数offset
         */
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0))
        
        refreshImageView.translatesAutoresizingMaskIntoConstraints = false
        
        
        addConstraint(NSLayoutConstraint(item: refreshImageView, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: -35))
        
        addConstraint(NSLayoutConstraint(item: refreshImageView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0))
        
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: -35))
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0))

    }
    
    //MARK: 懒加载控件
    // 指示文字
    fileprivate lazy var messageLabel: UILabel = {
        let lab = UILabel()
        lab.textColor = UIColor.white
        lab.font = UIFont.systemFont(ofSize: 14)
        lab.textAlignment = .center
        lab.text = "正常中"
        return lab
    }()
    
    // 指示箭头
    fileprivate lazy var refreshImageView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    
    // 风火轮
    fileprivate lazy var indicatorView: UIActivityIndicatorView = UIActivityIndicatorView()
    
    // 析构函数
    deinit {
        // KVO需要手动移除
        self.scrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
    
}

extension HMRefreshControl{
    // 监听将要添加到哪个控件上 (newSuperview 父控件)
    override func willMove(toSuperview newSuperview: UIView?) {
        // 判断newSuperview是否为nil 而且是否是一个滚动视图
        guard let view = newSuperview as? UIScrollView else {
            return
        }
        // 记录
        scrollView = view
        // 使用KVO监听newSuperview属性变化 -> 注册观察者
        scrollView?.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions.new, context: nil)

    }
    
    // 通过KVO监听方法来监听scrollView 属性变化
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        // 计算使用的临界值
        let contentOffsetMaxY = -(self.scrollView!.contentInset.top + refreshControlH)
        // 得到contentOffset
        let contentOffsetY = self.scrollView!.contentOffset.y
        //- 如果拖动中没有松手 (一共有两种状态 正常中 下拉中)
        if self.scrollView!.isDragging {
            //  - contentOffset.y >= -114  且 当前状态为下拉中 (正常中)
            if contentOffsetY >= contentOffsetMaxY && refreshControlType == .pulling {
                print("正常中")
                refreshControlType = .normal
            }else if contentOffsetY < contentOffsetMaxY && refreshControlType == .normal{
                // - contentOffset.y < -114 且 当前状态为正常中 (下拉中)
                print("下拉中")
                refreshControlType = .pulling
            }
        }else{
            //- 如果拖动后松手
            // - 如果当前的状态为下拉中 那么就要进入刷新中
            if refreshControlType == .pulling {
                refreshControlType = .refreshing
                print("刷新中")
            }
        }
    }
}







